home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / devel / lisp / akcl_lin.z / akcl_lin / h / arith.h next >
Encoding:
C/C++ Source or Header  |  1993-03-08  |  6.2 KB  |  268 lines

  1. #ifndef lsub
  2. #ifdef AIX3
  3. #define ulong ulong_
  4. #endif
  5. #ifndef linux
  6. typedef unsigned long ulong;
  7. #endif
  8. ulong overflow, hiremainder;
  9. #endif
  10.  
  11. #ifndef WSIZ
  12. #define WSIZ 32
  13.  
  14.  
  15. /*  Notation: if A and B are unsigned 32 bit integers,
  16.     1)  A:B signifies the 64 bit integer A*2^32 + B
  17.     2)  S(A:B) the signed 64 bit integer
  18.     3)  I(x) is a true integer.   If (x) were unsigned then
  19.         I(x) >= 0, otherwise I(x) has the same sign and size as x. 
  20.  
  21.   */
  22.  
  23. /* TEMPVARS are variables are used to prevent double evaluation
  24.   of arguments in macros, and also to make sure of the type.
  25.   Be careful about the composition of macros
  26. */
  27.  
  28. #define TEMPVARS ulong Xtx,Xty,Xtres;
  29.  
  30. /*
  31.   ulong res,x,y; res = addll(x,y);
  32.         then
  33.    I(overflow:res) == I(x) + I(y);
  34. */   
  35.  
  36. #define addll(x,y) \
  37.        (Xtx=(x),Xty=(y), Xtres = Xtx+Xty, \
  38.          overflow = \
  39.          (Xtres < Xtx ? 1:0), Xtres)
  40.  
  41. /*
  42.    ulong res,x,y; o = overflow; res = addllx(x,y);
  43.             then
  44.    I(overflow:res) == I(x) + I(y) +I(o).
  45. */
  46.  
  47. #ifndef addllx
  48. #define addllx(x,y) \
  49.   (Xtx=(x),Xtres= Xtx + (y), \
  50.    (Xtres < Xtx ? (Xtres += overflow ,overflow=1,Xtres) : \
  51.     (  Xtres += overflow , \
  52.      overflow = (Xtres < overflow ? 1 : 0), \
  53.      Xtres)))
  54. #endif
  55.  
  56.  /* ulong x,y,w,o;
  57.     if we do  o = overflow, res = subll(x,y) then
  58.      I(S(-overflow:res))  == I(x) -I(y);
  59.    */
  60. #ifndef subll
  61. #define subll(x,y) \
  62.   (Xtx=(x),Xty=(y),Xtres= Xtx - Xty, \
  63.      overflow = (Xtx >= Xty ? 0 : 1), Xtres)
  64. #endif
  65.  
  66. /*  ulong x,y,o,res; o = overflow; res= subllx(x,y);
  67.            then
  68.       I(S(-overflow):res) == I(x) - I(y) -I(o) 
  69.     where overflow is in {0,1} at all times.
  70. */
  71.  
  72. #ifndef subblx
  73. #define subllx(x,y) \
  74.   (Xtx=(x),Xty=(y),Xtres= Xtx - Xty, Xtres -=overflow, \
  75.    (Xty > Xtx ?  overflow = 1 : \
  76.     Xty < Xtx ?  overflow = 0 : 0), \
  77.    Xtres)
  78. #endif
  79.  
  80. #define shiftlr(x,y) \
  81.        (Xtx = x,  hiremainder=Xtx<<(32-y),Xtx>>y)
  82.  
  83. #define shiftl(x,y) \
  84.        (Xtx = x,  hiremainder=Xtx>>(32-y),Xtx<<y)
  85.  
  86.  
  87. #define llsub(h1,l1,h,l) \
  88. do{int tem= (int)l - (int) l1; \
  89.      if((UINT)l1> (UINT) l) (UINT) h--; \
  90.    l= (int)l - (int) l1; \
  91.    h=h-h1;\
  92. } while (0) 
  93.  
  94. /* x is less than WSIZ and it is shifted n bits into hi and lo */
  95.  
  96. #define llshift(x,n,hi,lo) \
  97. do { hi = x >> (WSIZ - n) ; \
  98.      lo = x << n ; \
  99.   }while (0)
  100.  
  101. #define UINT unsigned int
  102.  
  103.  
  104.     
  105. #define lladd(h1,l1,h,l) \
  106. do {UINT res; res=(UINT)l1+(UINT)l; \
  107.  if ((UINT)res< (UINT)l1 || (UINT)res< (UINT)l) \
  108.    /* overflow */ \
  109.    (h)++;  \
  110.      l=res; \
  111.     h= (UINT)h+(UINT)h1; \
  112. }while (0)
  113.  
  114.  
  115.    /* x,y unsigned longs.
  116.      u = x + y  if (u > 2^32)  h = h+1; */
  117. #ifndef add_carry
  118. #define add_carry(x,y,h) \
  119.   (Xtx = (x), Xtres = Xtx +(y), (Xtres < Xtx ? (h++,1):0), Xtres)
  120. #endif
  121. #endif
  122.  
  123. #ifndef BASE_COUNTER 
  124. #define BASE_COUNTER 0
  125. #endif
  126.  
  127.  
  128. #define divll(x,y) divul(x,y,hiremainder)
  129.  
  130. /*  ulong x,y,h, res; hi = rem;  res = divul(x,y,rem)
  131.            then
  132.     I(hi:x) ==  I(y) * I(res) + I(rem)
  133.         and  ( 0 = < rem < y)
  134. */
  135.  
  136. #ifndef divul
  137. #define divul(x,y,h) divul3(x,y,&h)
  138. #endif
  139.  
  140. /*  ulong x,y,h, res; res = mulul(x,y,h)
  141.            then
  142.     I(h:res) ==  I(x) * I(y);
  143. */
  144. #ifndef mulul
  145. #define mulul(x,y,h) mulul3(x,y,&h)
  146. #endif
  147.  
  148. #ifndef addmul
  149. #define addmul(x,y) \
  150.   (Xtx = hiremainder, Xtres = mulul(x,y,hiremainder),\
  151.    add_carry(Xtx,Xtres,hiremainder))
  152. #endif
  153.  
  154. #ifdef SET_MACHINE_CARRY
  155.              
  156. #define ADDLLX(x,y,z) \
  157.   SET_MACHINE_CARRY(overflow); \
  158.   (z) = ADDXCC((x),(y)); \
  159.   SET_OVERFLOW
  160.  
  161. #define SUBLLX(x,y,z) \
  162.   SET_MACHINE_CARRY(overflow); \
  163.   (z) = SUBXCC((x),(y)); \
  164.   SET_OVERFLOW
  165.  
  166.  
  167. #ifdef C_SWITCH_DOESNT_AFFECT_CARRY
  168.  
  169. #define CASE(i,op) case i: MP_NEXT_UP(zp) = op(MP_NEXT_UP(xp),(MP_NEXT_UP(yp)))
  170.  
  171. #define QUICK_LOOP(j,op) \
  172.   do{SET_MACHINE_CARRY(overflow); \
  173.   switch(j){ \
  174.   default:  \
  175.     CASE(16,op); \
  176.     CASE(15,op); \
  177.     CASE(14,op); \
  178.     CASE(13,op); \
  179.     CASE(12,op); \
  180.     CASE(11,op); \
  181.     CASE(10,op); \
  182.     CASE(9,op); \
  183.     CASE(8,op); \
  184.     CASE(7,op); \
  185.     CASE(6,op); \
  186.     CASE(5,op); \
  187.     CASE(4,op); \
  188.     CASE(3,op); \
  189.     CASE(2,op); \
  190.     CASE(1,op); \
  191.   case 0: SET_OVERFLOW; j -= 16;}} while (j > 0)
  192.  
  193. #else
  194. /* The C switch statement changes the machine carry, so
  195.    that we must reset it each time we enter */
  196.   
  197. #define LA(i,op)  L ## op ## i:  MP_NEXT_UP(zp) = \
  198.   op(MP_NEXT_UP(xp),MP_NEXT_UP(yp))
  199. #define CA(i,op) case i: SET_MACHINE_CARRY(overflow);\
  200.   goto L ## op ## i
  201. #define QUICK_LOOP(j,op) \
  202.  do {switch (j) { default: \
  203.  CA(16,op);CA(15,op);CA(14,op);CA(13,op);CA(12,op);CA(11,op);CA(10,op); \
  204.  CA(9,op);CA(8,op);CA(7,op);CA(6,op);CA(5,op);CA(4,op);CA(3,op); \
  205.  CA(2,op);CA(1,op); \
  206.  LA(16,op);LA(15,op);LA(14,op);LA(13,op);LA(12,op);LA(11,op);LA(10,op); \
  207.  LA(9,op);LA(8,op);LA(7,op);LA(6,op);LA(5,op);LA(4,op);LA(3,op);LA(2,op);\
  208.  LA(1,op); \
  209.  SET_OVERFLOW; j -= 16;}} while (j > 0)
  210.  
  211.  /* end  else C_SWITCH_DOESNT_AFFECT_CARRY */
  212. #endif 
  213.  
  214.     /* endif don't use machine carry in separate ops */
  215. #endif             
  216.  
  217.              
  218. #ifndef ADDLLX
  219. #define ADDLLX(x,y,z) (z) = addllx((x),(y))
  220. #endif
  221. /* z=x-y-overflow */
  222. #ifndef SUBLLX
  223. #define SUBLLX(x,y,z) (z) = subllx((x),(y))
  224. #endif
  225.  
  226. #ifndef mulll
  227. #define mulll(x,y) mulul(x,y,hiremainder)
  228. #endif
  229.  
  230. #ifndef mulul
  231. #define mulul(a,b,h) mulul3(a,b,&h)
  232. #endif
  233.  
  234. /*  The following macros are for stepping through
  235.     a bignum , after positioning a pointer at the
  236.     high or low word.
  237. */    
  238.  
  239. #define MP_START_LOW(u,x,l)  u = (x)+l
  240. #define MP_START_HIGH(u,x,l)  u = (x)+2
  241. #define MP_NEXT_UP(u) (*(--(u)))
  242. #define MP_NEXT_DOWN(u) (*((u)++))
  243.   /* ith word from the least significant */
  244. #define MP_ITH_WORD(u,i,l) (u)[l-i-1]
  245. #define MP_CODE_WORDS 2
  246. /* MP_LOW(x,lgef(x)) is the least significant  word */
  247. #define MP_LOW(x,l) ((x)[(l)-1])
  248. /* most significant word if l is the lgef(x) */  
  249. #define MP_HIGH(x,l) (x)[2]
  250.  
  251.   /*Some machines will iterate more efficiently with different bottoms
  252. for the iteration.  Eg with gcc and mc68k one can generate the dbra
  253. instruction which is done when i == -1.  The dbra does not alter the
  254. condition code which can be important in a tight loop.  */
  255.  
  256. #define MP_COUNT_LG(l)  COUNT(l - MP_CODE_WORDS )
  257.   /* i should be the number of counts so if i = COUNT(3)
  258.      WHILE_COUNT(--i) will repeat body 3 times. */
  259. #define  COUNT(l) (l +1+BASE_COUNTER)
  260. #define WHILE_COUNT(l) while (l!=BASE_COUNTER)
  261.  
  262. extern ulong ABS_MOST_NEGS[];
  263. extern ulong MOST_NEGS[];
  264.  
  265.  
  266.  
  267.      
  268.